package cn.HuanG.user.service.impl;

import cn.HuanG.user.constant.WxConstants;
import cn.HuanG.user.domain.LoginInfo;
import cn.HuanG.user.domain.User;
import cn.HuanG.user.domain.WxUser;
import cn.HuanG.user.mapper.LoginInfoMapper;
import cn.HuanG.user.mapper.UserMapper;
import cn.HuanG.user.mapper.WxUserMapper;
import cn.HuanG.user.service.IWxUserService;
import cn.HuanG.util.AjaxResult;
import cn.HuanG.util.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WxUserServiceImpl implements IWxUserService {
    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginInfoMapper loginInfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public AjaxResult wxLogin(Map<String, String> map) {
        //通过url获取token
        //封装常用类，将code拼接
        String url = WxConstants.GET_ACK_URL
                .replace("APPID",WxConstants.APPID)
                .replace("SECRET",WxConstants.SECRET)
                .replace("CODE",map.get("code"));
        System.out.println(url);
        //发送获取string类型的数据
        String s = HttpClientUtils.httpGet(url);
        System.out.println(s);
        //4、获取openid
        //			使用阿里巴巴的工具fastJson将string转换为json
        JSONObject jsonObject = JSON.parseObject(s);
        //获取json里面的openid
        String openId = jsonObject.getString("openid");
        //获取json里面的token
        String access_token = jsonObject.getString("access_token");
        //再通过openid查询数据库
        WxUser wxUser = wxUserMapper.loadByOpenId(openId);
        System.out.println("微信"+wxUser);
        //如果数据库有数据就是老用户
        if (wxUser!=null){
            //老用户免密登录
            //通过wxuser表中的userid获取user表的数据
            User user = userMapper.queryById(wxUser.getUser_id());
            //通过user表中的logininfoid获取logininfo表的数据
            LoginInfo loginInfo = loginInfoMapper.findByLoginInfoId(user.getLogininfo_id());
            //获取后然后返回前端，前端跳转到主页
            return noPwdLogin(loginInfo);
        }

            return AjaxResult.me().setMessage("binder").setResultObj("/binder.html?openid="+openId+"&access_token="+access_token);
    }

    @Override
    public AjaxResult bind(Map<String, String> map) {
        //获取手机号
        String phone = map.get("phone");
        //获取验证码
        String code = map.get("code");
        String openid = map.get("openid");
        String access_token = map.get("access_token");
        //从redis中获取验证，判断验证码是否正确
        String codeInredis = (String)redisTemplate.opsForValue().get(phone + ":BINDER");
        System.out.println("类型："+codeInredis);
        //新用户绑定数据
        if(codeInredis!=null){
            //将数据库的code取出，并且隔开时间戳
           codeInredis =  codeInredis.split(":")[0];
          if (!code.equals(codeInredis)){
              return new AjaxResult("验证填错鸟");
          }
        }else {
            return new AjaxResult("你个dsb，验证码没填");
        }
        //获取微信的个人信息
        //调用方法发送url
        String url=WxConstants.GET_USERINFO_URL
                .replace("ACCESS_TOKEN",access_token)
                .replace("OPENID",openid);
        String infoResult = HttpClientUtils.httpGet(url);
        //打印用户数据
        System.out.println(infoResult);
        //把微信用户的个人信息 解析
        /*
            {"openid":"oa9wA010o369pKmXk_zwRADRudBE"
            ,"nickname":"🐳航",
            "sex":0,
            "language":"",
            "city":"",
            "province":"",
            "country":""
            ,"headimgurl":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/BF6K1pR632XaPjrRiciauQFnBBiaCHr647NrJht84zD0TpRy5DYnicYRjfX59iaMXysSRECwowRsbPzu332RdEsUuXw\/132",
            "privilege":[],
            "unionid":"ovnCWw-HTEbkqdiBVakzTr9oBWE8"
            }

         */
        //使用阿里巴巴的工具将string转换成string
        JSONObject jsonObject = JSON.parseObject(infoResult);
        //创建微信用户将微信的个人信息保存到数据库
        WxUser wxUser = new WxUser();
        wxUser.setOpenid(openid);
        wxUser.setNickname(jsonObject.getString("nickname"));
        wxUser.setSex(jsonObject.getInteger("sex"));
        wxUser.setHeadimgurl(jsonObject.getString("headimgurl"));
        wxUser.setUnionid(jsonObject.getString("unionid"));

        //2.通过phone查找t_user表 判断用户是否已经注册
        User user = userMapper.loadByPhone(phone);
        LoginInfo loginInfo=null;
        //2.1 如果user不为空
        if (user==null){
            //2.2 如果user为空
            //2.2.1 生成一个t_user  ---生成一个loginInfo   微信个人信息生成wxuser和user绑定
            user=new User();
            user.setPhone(phone);
            user.setUsername("p_"+phone);
            user.setState(1);
            user.setCreatetime(new Date());
            //将生成的user数据再装到logininfo的数据库中
            loginInfo =user2LoginInfo(user);
            //保存loginInfo 返回新增数据的主键
            loginInfoMapper.save(loginInfo);
            //获取主键绑定，再在user表中生成一个与logininfo表相关联的主键id
            user.setLogininfo_id(loginInfo.getId());
            userMapper.save(user);
        }

        //获取用户在user表中的数据id进行绑定到wxuser表的数据库中，然后保存
        wxUser.setUser_id(user.getId());
        wxUserMapper.save(wxUser);
        if(user!=null){
            loginInfo = loginInfoMapper.queryById(user.getLogininfo_id());
        }
//        //如果不判断会多执行这一步。因为logininfo是有值的，不用再次去查询
//        loginInfo = loginInfoMapper.queryById(user.getLogininfo_id());
        //免密登录
        return noPwdLogin(loginInfo);
    }

    private LoginInfo user2LoginInfo(User user) {
        //创建一个logininfo对象
        LoginInfo loginInfo = new LoginInfo();
        //将user表的数据copy到logininfo数据表中
        BeanUtils.copyProperties(user,loginInfo);
        //设置初始值
        loginInfo.setType(1);
        loginInfo.setDisable(1);
        return loginInfo;
    }


    //免密登录的 数据的处理
    private AjaxResult noPwdLogin(LoginInfo loginInfo){
        //生成token
        String token = UUID.randomUUID().toString();
        //把当前用户和token 放到redis里面  并设置有效期是30分钟
        redisTemplate.opsForValue().set(token,loginInfo,30, TimeUnit.MINUTES);
        //把 token  登录用户 返回给前端
        Map<String,Object> map = new HashMap();
        map.put("TOKEN",token);
        //返回给前端以前 清空敏感数据
        loginInfo.setPassword(null);
        loginInfo.setSalt(null);

        map.put("loginInfo",loginInfo);
        return AjaxResult.me().setResultObj(map);
    }
}
